#include "plBullet.h"
#include "plbtaobindings.h"
#include "../core/LuaUtils.h"


void plbtAOBindings::pushStaticFuncs(lua_State* L)
{
	static const struct luaL_Reg mylib [] = {
		{"CreateRigidBody", li_createRigidBody},
		{"CreateShape", li_createShape},
		{"CreateConstraint", li_createConstraint},
		{"GetBody", li_getBody},
		{"GetShape", li_getShape},
		{"GetConstraint", li_getConstraint},
		{"DeleteBody", li_deleteBody},
		{"DeleteConstraint", li_deleteConstraint},
		{"DeleteShape", li_deleteShape},
		{"InitPhysics", li_initPhysics},
		{"SetGravity", li_setGravity},
		{"SetInternalTimestep", li_setInternalTimestep},
		{"StepSimulation", li_stepSimulation},
		{"SetMaxSubsteps", li_setMaxSubsteps},
		{"SetAutoStep", li_setAutoStep},
		{"MakeVector", li_makeVector},
		{"MakeQuaternion", li_makeQuaternion},
		{"MakeTransform", li_makeTransform},
		{NULL, NULL}  /* sentinel */
	};

	// dump them into said table
	luaL_register(L, NULL, mylib);
}

int plbtAOBindings::li_createRigidBody(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	PlRigidBody* ret = op->createRigidBody();
	push_custom_reffed<PlRigidBody>(L, ret, "PlRigidBody");
	return 1;
}


int plbtAOBindings::li_createShape(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	std::string a1 = getSafeLuaString(L, 2);
	PlShape* ret = op->createShape(a1);
	push_custom_reffed<PlShape>(L, ret, "PlShape");
	return 1;
}


int plbtAOBindings::li_createConstraint(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	PlConstraint* ret = op->createConstraint();
	push_custom_reffed<PlConstraint>(L, ret, "PlConstraint");
	return 1;
}


int plbtAOBindings::li_getBody(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int a1 = (int)lua_tointeger(L, 2);
	PlRigidBody* ret = op->getBody(a1);
	push_custom_reffed<PlRigidBody>(L, ret, "PlRigidBody");
	return 1;
}


int plbtAOBindings::li_getShape(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	std::string a1 = getSafeLuaString(L, 2);
	PlShape* ret = op->getShape(a1);
	push_custom_reffed<PlShape>(L, ret, "PlShape");
	return 1;
}


int plbtAOBindings::li_getConstraint(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int a1 = (int)lua_tointeger(L, 2);
	PlConstraint* ret = op->getConstraint(a1);
	push_custom_reffed<PlConstraint>(L, ret, "PlConstraint");
	return 1;
}


int plbtAOBindings::li_deleteBody(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	PlRigidBody* a1 = pop_custom_reffed<PlRigidBody>(L, 2, "PlRigidBody"); if(a1 == NULL){ LOG(logERROR) << "Null input."; return 0; }
	op->deleteBody(a1);
	
	return 0;
}


int plbtAOBindings::li_deleteConstraint(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	PlConstraint* a1 = pop_custom_reffed<PlConstraint>(L, 2, "PlConstraint"); if(a1 == NULL){ LOG(logERROR) << "Null input."; return 0; }
	op->deleteConstraint(a1);
	
	return 0;
}


int plbtAOBindings::li_deleteShape(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	PlShape* a1 = pop_custom_reffed<PlShape>(L, 2, "PlShape"); if(a1 == NULL){ LOG(logERROR) << "Null input."; return 0; }
	op->deleteShape(a1);
	
	return 0;
}


int plbtAOBindings::li_initPhysics(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	op->initPhysics();
	
	return 0;
}


int plbtAOBindings::li_setGravity(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	btVector3* temp1 = pop_custom<btVector3>(L, 2, "btVector3"); if(temp1 == NULL){ LOG(logERROR) << "Null input."; return 0; } btVector3& a1 = *temp1;
	op->setGravity(a1);
	
	return 0;
}


int plbtAOBindings::li_setInternalTimestep(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	double a1 = (double)lua_tonumber(L, 2);
	op->setInternalTimestep(a1);
	
	return 0;
}


int plbtAOBindings::li_stepSimulation(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	double a1 = (double)lua_tonumber(L, 2);
	op->stepSimulation(a1);
	
	return 0;
}


int plbtAOBindings::li_setMaxSubsteps(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	int a1 = (int)lua_tointeger(L, 2);
	op->setMaxSubsteps(a1);
	
	return 0;
}


int plbtAOBindings::li_setAutoStep(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	bool a1 = (lua_toboolean(L, 2) > 0);
	op->setAutoStep(a1);
	
	return 0;
}


int plbtAOBindings::li_makeVector(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	btVector3 ret = op->makeVector();
	push_custom<btVector3>(L, &ret, "btVector3");
	return 1;
}


int plbtAOBindings::li_makeQuaternion(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	btQuaternion ret = op->makeQuaternion();
	push_custom<btQuaternion>(L, &ret, "btQuaternion");
	return 1;
}


int plbtAOBindings::li_makeTransform(lua_State* L)
{
	PlBullet* op = (PlBullet*)typeCheckUnboxAO(L,1,"PlBullet");
	if(op == NULL){
		LOG(logERROR) << "Null self!";
	return 0;}
	btTransform ret = op->makeTransform();
	push_custom<btTransform>(L, &ret, "btTransform");
	return 1;
}


